package com.pactera.madp.cp.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pactera.madp.common.core.exception.CheckedException;
import com.pactera.madp.common.security.util.SecurityUtils;
import com.pactera.madp.cp.api.dto.WorkContactTagUserCreateDTO;
import com.pactera.madp.cp.api.dto.WxTagDTO;
import com.pactera.madp.cp.api.dto.crm.CrmCustomQueryConditionDTO;
import com.pactera.madp.cp.api.dto.workcontacttag.WorkContactTagGroupUpdateDTO;
import com.pactera.madp.cp.api.dto.workcontacttag.WorkContactTagsAddDTO;
import com.pactera.madp.cp.api.em.workcontact.EventEnum;
import com.pactera.madp.cp.api.em.workupdatetime.TypeEnum;
import com.pactera.madp.cp.api.entity.*;
import com.pactera.madp.cp.api.entity.crm.WorkCustTagInfoEntity;
import com.pactera.madp.cp.api.entity.crm.WorkCustomInfoEntity;
import com.pactera.madp.cp.api.model.workcontacttag.ContactTagId;
import com.pactera.madp.cp.api.model.workcontacttag.GetContactTapModel;
import com.pactera.madp.cp.api.model.workcontacttag.GetEmployeeTagModel;
import com.pactera.madp.cp.api.page.SubPage;
import com.pactera.madp.cp.api.vo.*;
import com.pactera.madp.cp.common.util.WxApiUtils;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.mapper.WorkContactTagMapper;
import com.pactera.madp.cp.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhaojinjian
 * @ClassName WorkContactTagServiceImpl.java
 * @Description TODO
 * @createTime 2020/12/3 14:30
 */
@Slf4j
@Service
public class WorkContactTagServiceImpl extends ServiceImpl<WorkContactTagMapper, WorkContactTagEntity> implements IWorkContactTagService {

    @Autowired
    private IWorkContactTagPivotService contactTagPivotService;
    @Autowired
    private IWorkContactTagGroupService contactTagGroupService;
    @Autowired
    private IWorkUpdateTimeService workUpdateTimeService;
    @Autowired
    private IWorkEmployeeService employeeService;
    @Autowired
    private IWorkContactService contactService;
    @Autowired
    private IWorkContactTagService tagService;
    @Autowired
    private ContactEmployeeTrackService contactEmployeeTrackService;
    @Autowired
    private IWorkEmployeeService workEmployeeService;
    @Autowired
    private IContactService iContactService;
    @Autowired
    private IWorkContactEmployeeService workContactEmployeeService;
    @Autowired
    private WorkCustomInfoService workCustomInfoService;
    @Autowired
    private WorkCustTagInfoService workCustTagInfoService;

    @Override
    public List<GetContactTapModel> getContactTapName(Integer empId, Integer contactId) {
        List<GetContactTapModel> list = new ArrayList<>();
        List<Integer> contactTagId = contactTagPivotService.getContactTapId(empId, contactId);
        if (contactTagId == null || contactTagId.size() < 1) {
            return list;
        }

        QueryWrapper<WorkContactTagEntity> tagWrapper = new QueryWrapper<>();
        tagWrapper.select("id", "name");
        tagWrapper.in("id", contactTagId)
                  .orderByDesc("create_time");
        List<WorkContactTagEntity> tags = this.list(tagWrapper);
        tags.forEach(item -> {
            GetContactTapModel model = new GetContactTapModel();
            model.setTagId(item.getId());
            model.setTagName(item.getName());
            list.add(model);
        });
        return list;
    }

    @Override
    public List<GetEmployeeTagModel> getEmployeeTapName(Integer empId) {
        List<GetEmployeeTagModel> list = new ArrayList<>();
        QueryWrapper<WorkContactTagPivotEntity> tagPivotWrapper = new QueryWrapper();
        tagPivotWrapper.eq("employee_id", empId);
//        tagPivotWrapper.isNull("deleted_at");
        List<ContactTagId> tagPivot = contactTagPivotService.getContactTapId(empId);
        if (tagPivot != null && tagPivot.size() > 0) {
            List<Integer> contactTagId = tagPivot.stream().map(ContactTagId::getTagId).collect(Collectors.toList());
            QueryWrapper<WorkContactTagEntity> tagWrapper = new QueryWrapper<>();
            tagWrapper.select("id,name,`order`");
            tagWrapper.in("id", contactTagId);
//            tagWrapper.isNull("deleted_at");
            List<WorkContactTagEntity> tags = this.list(tagWrapper);
            if (tags != null && tags.size() > 0) {
                tagPivot.forEach(item -> {
                    GetEmployeeTagModel model = new GetEmployeeTagModel();
                    model.setContactId(item.getContactId());
                    model.setTagId(item.getTagId());
                    Optional<WorkContactTagEntity> op = tags.stream().filter(tag -> tag.getId() == item.getTagId()).findAny();
                    model.setTagName(op.get().getName());
                    model.setEmpId(item.getEmpId());
                    list.add(model);
                });
            }
        }
        return list;
    }

    @Override
    public List<GetEmployeeTagModel> getEmployeeTapName(List<Integer> empIds) {
        List<ContactTagId> tagPivot = contactTagPivotService.getContactTapId(empIds);
        if (Objects.isNull(tagPivot) || tagPivot.isEmpty()) {
            return Collections.emptyList();
        }

        List<Integer> contactTagId = tagPivot.stream().map(ContactTagId::getTagId).collect(Collectors.toList());
        QueryWrapper<WorkContactTagEntity> tagWrapper = new QueryWrapper<>();
        tagWrapper.select("id,name,`order`");
        tagWrapper.in("id", contactTagId);
//        tagWrapper.isNull("deleted_at");
        List<WorkContactTagEntity> tags = this.list(tagWrapper);
        List<GetEmployeeTagModel> list = new ArrayList<>();
        tagPivot.forEach(item -> {
            GetEmployeeTagModel model = new GetEmployeeTagModel();
            model.setContactId(item.getContactId());
            model.setTagId(item.getTagId());
            Optional<WorkContactTagEntity> op = tags.stream().filter(tag -> tag.getId() == item.getTagId()).findAny();
            model.setTagName(op.get().getName());
            model.setEmpId(item.getEmpId());
            list.add(model);
        });
        return list;
    }

    @Override
    public List<String> getWXContactTagId(List<Integer> tagIds) {
        List<WorkContactTagEntity> list = this.baseMapper.selectBatchIds(tagIds);
        if (list.isEmpty()) {
            return null;
        }
        return list.stream().filter(l->!l.getWxContactTagId().equals("")).map(WorkContactTagEntity::getWxContactTagId).collect(Collectors.toList());
    }

    @Override
    public Map<String, Integer> getContactTagIds(List<Integer> tagId) {
        log.info("tagId:",tagId);
        if (tagId == null || tagId.isEmpty()) {
            return new HashMap<>();
        }
        QueryWrapper<WorkContactTagEntity> wrapper = new QueryWrapper();
        wrapper.select("id,wx_contact_tag_id");
        wrapper.in("id", tagId);
        wrapper.ne("wx_contact_tag_id","");
        List<WorkContactTagEntity> contactTag = this.list(wrapper);
        log.info("contactTag:{}",contactTag);
        if (contactTag == null || contactTag.isEmpty() || contactTag.size() <= 0) {
            return new HashMap<>();
        }
        return contactTag.stream().collect(Collectors.toMap(entry -> entry.getWxContactTagId(), entry -> entry.getId()));
    }

    @Override
    public Map<String, Integer> getContactTagId(List<String> wx_tagId) {
        if (wx_tagId.isEmpty()) {
            return new HashMap<>();
        }
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.select("id,wx_contact_tag_id");
        wrapper.in("wx_contact_tag_id", wx_tagId);
        wrapper.ne("wx_contact_tag_id","");
        List<WorkContactTagEntity> contactTag = this.list(wrapper);
        if (contactTag == null || contactTag.isEmpty() || contactTag.size() <= 0) {
            return new HashMap<>();
        }
        return contactTag.stream().collect(Collectors.toMap(entry -> entry.getWxContactTagId(), entry -> entry.getId()));
    }

    @Override
    public Map<String, Integer> getContactTagId(Integer corpId) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.select("id,wx_contact_tag_id");
        wrapper.eq("corp_id", corpId);
        wrapper.ne("wx_contact_tag_id","");
//        wrapper.isNull("deleted_at");
        List<WorkContactTagEntity> contactTag = this.list(wrapper);
        if (contactTag == null || contactTag.isEmpty() || contactTag.size() <= 0) {
            return new HashMap<>();
        }
        return contactTag.stream().collect(Collectors.toMap(entry -> entry.getWxContactTagId(), entry -> entry.getId()));
    }

    /**
     * 客户标签管理 - 列表
     */
    @Override
    public Page<List<ContactTagIndexVO>> getTagList(Integer tagGroupId, Page page) {
        int corpId = CorpContextHolder.getCorpId();
        tagGroupId = tagGroupId == null ? 0 : tagGroupId;
//        Page<WorkContactTagEntity> page = ApiRespUtils.initPage(requestPage);
        lambdaQuery().select(WorkContactTagEntity::getId, WorkContactTagEntity::getName)
                .eq(WorkContactTagEntity::getCorpId, corpId)
                .eq(WorkContactTagEntity::getContactTagGroupId, tagGroupId)
                .page(page);

        List<WorkContactTagEntity> tagEntityList = page.getRecords();
        List<ContactTagIndexVO> voList = new ArrayList<>();
        for (WorkContactTagEntity entity : tagEntityList) {
            ContactTagIndexVO vo = new ContactTagIndexVO();
            vo.setId(entity.getId());
            vo.setName(entity.getName());
            Integer count = contactTagPivotService.lambdaQuery()
                    .eq(WorkContactTagPivotEntity::getContactTagId, entity.getId())
                    .count();
            vo.setContactNum(count == null ? 0 : count);
            voList.add(vo);
        }

        String syncTagTime = workUpdateTimeService.getLastUpdateTime(TypeEnum.TAG);

//        RespPageVO respPageVO = RespPageVO.getInstance(page);
//        Map<String, Object> map = new HashMap<>(3);
//        map.put("list", voList);
//        map.put("syncTagTime", syncTagTime);   //TODO 该字段暂时不知道作用，联调时确定

        SubPage subPage = new SubPage();
        subPage.setRecords(voList);
        subPage.setCurrent(page.getCurrent());
        subPage.setSize(page.getSize());
        subPage.setTotal(page.getTotal());
        return subPage;
    }

    /**
     * 删除标签
     */
    @Override
    public void deleteTag(String tagIds) {
        int corpId = CorpContextHolder.getCorpId();

        String[] ids = tagIds.split(",");
        List<WorkContactTagEntity> tagEntityList = this.list(
                new QueryWrapper<WorkContactTagEntity>()
                        .select("id", "wx_contact_tag_id")
                        .eq("corp_id", corpId)
                        .in("id", Arrays.asList(ids))
        );

        List<String> wxTagIds = new ArrayList<>();
        for (WorkContactTagEntity tagEntity : tagEntityList) {
            wxTagIds.add(tagEntity.getWxContactTagId());
            this.baseMapper.deleteById(tagEntity.getId());

            // 删除客户标签关联表
            List<Integer> tagPivotIdList = contactTagPivotService.lambdaQuery()
                    .select(WorkContactTagPivotEntity::getId)
                    .eq(WorkContactTagPivotEntity::getContactTagId, tagEntity.getId())
                    .list()
                    .stream()
                    .map(WorkContactTagPivotEntity::getId)
                    .collect(Collectors.toList());

            contactTagPivotService.removeByIds(tagPivotIdList);

        }

        // 删除微信标签
        WxApiUtils.requestDelTags(corpId, wxTagIds);

    }

    @Override
    public void deleteTagByGroupId(int corpId, int tagGroupId, boolean callWx) {
        List<WorkContactTagEntity> tagEntityList = this.list(
                new QueryWrapper<WorkContactTagEntity>()
                        .select("id")
                        .eq("corp_id", corpId)
                        .eq("contact_tag_group_id", tagGroupId)
        );

        List<Integer> tagIdList = new ArrayList<>();
        for (WorkContactTagEntity tagEntity : tagEntityList) {
            tagIdList.add(tagEntity.getId());
        }

        this.baseMapper.deleteBatchIds(tagIdList);

        // 删除客户标签关联表
        List<Integer> contactTagPivotIdList = contactTagPivotService.lambdaQuery()
                .select(WorkContactTagPivotEntity::getId)
                .in(WorkContactTagPivotEntity::getContactTagId, tagIdList)
                .list().stream().map(WorkContactTagPivotEntity::getId)
                .collect(Collectors.toList());
        contactTagPivotService.removeByIds(contactTagPivotIdList);
    }

    @Override
    public void synContactTag() {
        int corpId = CorpContextHolder.getCorpId();
        synContactTag(corpId);
    }

    /**
     * 同步客户标签
     */
    @Override
    public void synContactTag(int corpId) {
        String resultJson = WxApiUtils.requestGetAllTag(corpId);
        List<WxTagDTO> dtos = JSON.parseArray(resultJson, WxTagDTO.class);
        Map<String, WxTagDTO> wxGroupTagMap = new HashMap<>(0);
        for (WxTagDTO dto : dtos) {
            wxGroupTagMap.put(dto.getGroupId(), dto);
        }

        List<WorkContactTagGroupEntity> tagGroupEntities = contactTagGroupService.lambdaQuery()
                .eq(WorkContactTagGroupEntity::getCorpId, corpId)
                .list();

        for (WorkContactTagGroupEntity tagGroupEntity : tagGroupEntities) {
            String wxGroupId = tagGroupEntity.getWxGroupId();
            if (wxGroupTagMap.containsKey(wxGroupId)) {
                // 更新标签组和标签组下面的标签
                updateGroupTagAndTag(wxGroupTagMap.get(wxGroupId));
            } else {
                if (tagGroupEntity.getType().equals("1")) {
                    //如果是系统标签（CRM标签）直接跳过
                    continue;
                }
                // 删除标签组
                contactTagGroupService.removeById(tagGroupEntity.getId());
                // 删除标签组下面的标签
                List<Integer> contactTagIdList = lambdaQuery()
                        .select(WorkContactTagEntity::getId)
                        .eq(WorkContactTagEntity::getCorpId, corpId)
                        .eq(WorkContactTagEntity::getContactTagGroupId, tagGroupEntity.getId())
                        .list()
                        .stream().map(WorkContactTagEntity::getId)
                        .collect(Collectors.toList());

                for (Integer contactTagId : contactTagIdList) {
                    deleteTagAndPivotByTagId(contactTagId);
                }
            }
            wxGroupTagMap.remove(wxGroupId);
        }

        // 新增标签组
        for (WxTagDTO dto : wxGroupTagMap.values()) {
            WorkContactTagGroupEntity entity = new WorkContactTagGroupEntity();
            entity.setWxGroupId(dto.getGroupId());
            entity.setCorpId(corpId);
            entity.setGroupName(dto.getGroupName());
            entity.setOrder(dto.getOrder());
            entity.setCreateName(SecurityUtils.getUser().getUsername());

            // 事务隔离 创建标签组
            createTagGroup(entity);

            // 创建标签组下面的标签
            createTag(entity, dto);
        }

        // 更新 cp_work_update_time
        workUpdateTimeService.updateSynTime(corpId, TypeEnum.TAG);
    }

    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    void createTagGroup(WorkContactTagGroupEntity groupEntity) {
        contactTagGroupService.save(groupEntity);
    }

    private boolean createTag(WorkContactTagGroupEntity entity, WxTagDTO dto) {
        List<WxTagDTO.TagDTO> tagDTOList = dto.getTag();
        int count = 0;
        for (WxTagDTO.TagDTO tagDto : tagDTOList) {
            count++;
            createTag(entity, tagDto);
        }
        return count == tagDTOList.size();
    }

    private void updateGroupTagAndTag(WxTagDTO dto) {
        String wxGroupId = dto.getGroupId();
        WorkContactTagGroupEntity entity = new WorkContactTagGroupEntity();
        entity.setWxGroupId(wxGroupId);
        entity = contactTagGroupService.lambdaQuery()
                .eq(WorkContactTagGroupEntity::getWxGroupId, wxGroupId)
                .one();

        // 更新标签组
        entity.setGroupName(dto.getGroupName());
        entity.setOrder(dto.getOrder());
        entity.setCreateName(SecurityUtils.getUser().getUsername());
        contactTagGroupService.updateById(entity);

        List<WxTagDTO.TagDTO> tagDTOList = dto.getTag();
        List<WorkContactTagEntity> tagEntityList = this.list(
                new QueryWrapper<WorkContactTagEntity>()
                        .eq("corp_id", entity.getCorpId())
                        .eq("contact_tag_group_id", entity.getId())
        );

        Map<String, WxTagDTO.TagDTO> tagDTOMap = new HashMap<>(0);
        for (WxTagDTO.TagDTO tagDto : tagDTOList) {
            tagDTOMap.put(tagDto.getId(), tagDto);
        }

        for (WorkContactTagEntity tagEntity : tagEntityList) {
            String wxContactTagId = tagEntity.getWxContactTagId();
            if (tagDTOMap.containsKey(wxContactTagId)) {
                // 更新标签
                WxTagDTO.TagDTO tagDto = tagDTOMap.get(wxContactTagId);
                tagEntity.setName(tagDto.getName());
                tagEntity.setOrder(tagDto.getOrder());
                this.updateById(tagEntity);
            } else {
                // 删除标签
                deleteTagAndPivotByTagId(tagEntity.getId());
            }
            tagDTOMap.remove(wxContactTagId);
        }

        // 新增标签
        for (WxTagDTO.TagDTO tagDto : tagDTOMap.values()) {
            createTag(entity, tagDto);
        }
    }

    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    boolean createTag(WorkContactTagGroupEntity entity, WxTagDTO.TagDTO tagDto) {
        WorkContactTagEntity tagEntity = new WorkContactTagEntity();
        tagEntity.setWxContactTagId(tagDto.getId());
        tagEntity.setCorpId(entity.getCorpId());
        tagEntity.setName(tagDto.getName());
        tagEntity.setOrder(tagDto.getOrder());
        tagEntity.setContactTagGroupId(entity.getId());
        return this.save(tagEntity);
    }

    @Override
    public List<ContactTagVO> getAllTag(Integer tagGroupId,Integer corpId) {

        QueryWrapper<WorkContactTagEntity> wrapper = new QueryWrapper<>();
        wrapper.select("wx_contact_tag_id", "name","id");
        wrapper.eq("corp_id", corpId);
        if (tagGroupId != null) {
            wrapper.eq("contact_tag_group_id", tagGroupId);
        }

        List<WorkContactTagEntity> tagEntityList = this.list(wrapper);

        List<ContactTagVO> voList = new ArrayList<>();
        for (WorkContactTagEntity entity : tagEntityList) {
            ContactTagVO vo = new ContactTagVO();
            vo.setWxContactTagId(entity.getWxContactTagId());
            vo.setName(entity.getName());
            vo.setId(entity.getId());
            voList.add(vo);
        }

        return voList;
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public boolean createTag(Integer groupTagId, List<String> tagNameList) {
        int corpId = CorpContextHolder.getCorpId();

        WorkContactTagGroupEntity groupEntity = contactTagGroupService.getById(groupTagId);
        if (groupEntity == null) {
            throw new CheckedException("标签组不存在");
        }

        if (tagNameList.isEmpty()){
            throw new CheckedException("输入标签列表不能为空");
        }

        // 判断标签是否存在
        int count = lambdaQuery().eq(WorkContactTagEntity::getCorpId, corpId)
                .eq(WorkContactTagEntity::getContactTagGroupId, groupEntity.getId())
                .in(WorkContactTagEntity::getName, tagNameList)
                .count();
        if (count > 0) {
            throw new CheckedException("标签添加重复");
        }

        // 标签添加到微信
        String wxGroupId = groupEntity.getWxGroupId();
        String resultJson;
        // 创建微信标签
        if (wxGroupId == null || wxGroupId.isEmpty()) {
            String tagGroupName = groupEntity.getGroupName();
            resultJson = WxApiUtils.requestCreateGroupAndTags(corpId, tagGroupName, tagNameList);
        } else {
            resultJson = WxApiUtils.requestCreateTags(corpId, wxGroupId, tagNameList);
        }

        // 更新标签组
        WxTagDTO dto = JSON.parseObject(resultJson, WxTagDTO.class);
        if (wxGroupId == null || wxGroupId.isEmpty()) {
            wxGroupId = dto.getGroupId();
            groupEntity.setWxGroupId(wxGroupId);
            contactTagGroupService.updateById(groupEntity);
        }

        // 微信标签添加到数据库
        groupEntity.setCreateTime(DateUtil.toLocalDateTime(new Date()));
        return createTag(groupEntity, dto) ;
    }

    @Override
    public ContactTagDetailVO getTagDetail(Integer tagId) {
        if (tagId == null) {
            throw new CheckedException("标签 id 无效");
        }

        WorkContactTagEntity entity = this.baseMapper.selectById(tagId);
        if (entity == null) {
            throw new CheckedException("标签不存在");
        }

        ContactTagDetailVO vo = new ContactTagDetailVO();
        vo.setTagId(entity.getId());
        vo.setGroupId(entity.getContactTagGroupId());
        vo.setTagName(entity.getName());

        return vo;
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public void moveTags(String tagIds, Integer groupId) {
        if (tagIds == null || tagIds.isEmpty()) {
            throw new CheckedException("标签 id 无效");
        }

        List<WorkContactTagEntity> tagEntityList = this.baseMapper.selectBatchIds(Arrays.asList(tagIds.split(",")));
        Map<String, WorkContactTagEntity> tagMap = new HashMap<>(0);
        for (WorkContactTagEntity e : tagEntityList) {
            tagMap.put(e.getName(), e);
        }

        List<WorkContactTagEntity> exTagEntityList = this.list(
                new QueryWrapper<WorkContactTagEntity>()
                        .eq("corp_id", "")
                        .eq("contact_tag_group_id", groupId)
                        .in("name", tagMap.keySet())
        );

        if (!exTagEntityList.isEmpty()) {
            throw new CheckedException("移动到标签组失败, 标签重复");
        }

        int corpId = CorpContextHolder.getCorpId();

        // 删除微信标签
        List<String> wxTagIds = new ArrayList<>();
        for (WorkContactTagEntity e : tagEntityList) {
            wxTagIds.add(e.getWxContactTagId());
        }
        WxApiUtils.requestDelTags(corpId, wxTagIds);

        WorkContactTagGroupEntity groupEntity = contactTagGroupService.getById(groupId);

        // 添加微信标签
        String resultJson = WxApiUtils.requestCreateTags(corpId, groupEntity.getWxGroupId(), new ArrayList<>(tagMap.keySet()));
        WxTagDTO dto = JSON.parseObject(resultJson, WxTagDTO.class);
        List<WxTagDTO.TagDTO> tagDTOList = dto.getTag();
        for (WxTagDTO.TagDTO tagDTO : tagDTOList) {
            WorkContactTagEntity tagEntity = tagMap.get(tagDTO.getName());
            tagEntity.setWxContactTagId(tagDTO.getId());
            tagEntity.setContactTagGroupId(groupId);
            this.updateById(tagEntity);
        }
    }

    @Override
    public void updateTag(Integer tagId, Integer groupId, String tagName, Integer isUpdate) {
        if (isUpdate == 1) {
            WorkContactTagEntity entity = this.baseMapper.selectById(tagId);
            if (entity != null) {
                entity.setContactTagGroupId(groupId);
                entity.setName(tagName);
                this.updateById(entity);
                WxApiUtils.requestEditTag(entity.getCorpId(), entity.getWxContactTagId(), tagName);
            } else {
                throw new CheckedException("标签不存在");
            }
        }
    }

    @Override
    public boolean updateTagByGroup(WorkContactTagGroupUpdateDTO updateDTO) {
        List<WorkContactTagEntity> tagEntities = this.baseMapper.selectList(
                new QueryWrapper<WorkContactTagEntity>().eq("contact_tag_group_id", updateDTO.getGroupId()));
        List<String> list = updateDTO.getTagNameList();
        List<String> strings = new LinkedList<>();
        LinkedList<WorkContactTagEntity> entities = new LinkedList<>();
        for (WorkContactTagEntity tag:tagEntities) {
            for (String l:list) {
                if (tag.getName().equals(l)){
                    strings.add(l);
                  entities.add(tag);
                }
            }
        }
        list.removeAll(strings);
        tagEntities.removeAll(entities);
        if (list.size() != 0) {
            this.createTag(updateDTO.getGroupId(),list);
        }

        for (WorkContactTagEntity tag:tagEntities) {
            this.deleteTagAndPivotByTagId(tag.getId());
            WxApiUtils.requestDelTag(CorpContextHolder.getCorpId(),tag.getWxContactTagId());
        }
        return true;
    }

    @Override
    public void wxBackCreateTag(int corpId, String wxTagId) {
        String resultJson = WxApiUtils.requestGetTagDetail(corpId, wxTagId);
        WxTagDTO dto = JSON.parseArray(resultJson, WxTagDTO.class).get(0);
        WorkContactTagGroupEntity tagGroupEntity = getContactTagGroupEntity(dto.getGroupId());

        if (tagGroupEntity == null) {
            // 原因: 创建了一个新的标签组和标签, 标签的回调早于标签组
            // 处理: 可忽略
            log.error(">>> 微信回调 -> 创建标签: 标签组不存在");
            return;
        }

        WxTagDTO.TagDTO tagDTO = dto.getTag().get(0);
        WorkContactTagEntity tagEntity = new WorkContactTagEntity();
        tagEntity.setWxContactTagId(tagDTO.getId());
        tagEntity.setCorpId(corpId);
        tagEntity.setName(tagDTO.getName());
        tagEntity.setOrder(tagDTO.getOrder());
        tagEntity.setContactTagGroupId(tagGroupEntity.getId());
        this.save(tagEntity);
    }

    private WorkContactTagGroupEntity getContactTagGroupEntity(String wxTagGroupId) {
        return contactTagGroupService.lambdaQuery()
                .eq(WorkContactTagGroupEntity::getWxGroupId, wxTagGroupId)
                .one();
    }

    @Override
    public void wxBackUpdateTag(int corpId, String wxTagId) {
        String resultJson = WxApiUtils.requestGetTagDetail(corpId, wxTagId);
        WxTagDTO dto = JSON.parseArray(resultJson, WxTagDTO.class).get(0);
        WxTagDTO.TagDTO tagDTO = dto.getTag().get(0);

        WorkContactTagEntity tagEntity = this.list(
                new QueryWrapper<WorkContactTagEntity>()
                        .eq("wx_contact_tag_id", tagDTO.getId())
        ).get(0);

        WorkContactTagGroupEntity tagGroupEntity = getContactTagGroupEntity(dto.getGroupId());

        tagEntity.setName(tagDTO.getName());
        tagEntity.setOrder(tagDTO.getOrder());
        tagEntity.setContactTagGroupId(tagGroupEntity.getId());
        this.updateById(tagEntity);
    }

    @Override
    public void wxBackDeleteTag(int corpId, String wxTagId) {
        List<WorkContactTagEntity> tagEntityList = this.list(
                new QueryWrapper<WorkContactTagEntity>()
                        .eq("wx_contact_tag_id", wxTagId)
        );

        for (WorkContactTagEntity tagEntity : tagEntityList) {
            deleteTagAndPivotByTagId(tagEntity.getId());
        }
    }

    @Override
    public boolean labelPut(String wxContactTagId, String tagName) {
        WorkContactTagEntity one = getOne(Wrappers.<WorkContactTagEntity>lambdaQuery().eq(WorkContactTagEntity::getWxContactTagId, wxContactTagId));
        WorkContactTagEntity workContactTagEntity = new WorkContactTagEntity();
        workContactTagEntity.setId(one.getId());
        workContactTagEntity.setName(tagName);
        workContactTagEntity.setCorpId(one.getCorpId());
        workContactTagEntity.setOrder(one.getOrder());
        workContactTagEntity.setContactTagGroupId(one.getContactTagGroupId());
        QueryWrapper<WorkContactTagEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("id",one.getId());
        return  update(workContactTagEntity, wrapper);


    }

    /**
     * 删除客户标签并删除客户标签与客户关联数据
     */
    public void deleteTagAndPivotByTagId(int tagId) {
        List<Integer> contactTagPivotIdList = contactTagPivotService.lambdaQuery()
                .select(WorkContactTagPivotEntity::getId)
                .eq(WorkContactTagPivotEntity::getContactTagId, tagId)
                .list()
                .stream()
                .map(WorkContactTagPivotEntity::getId)
                .collect(Collectors.toList());
        if (!contactTagPivotIdList.isEmpty()) {
            contactTagPivotService.removeByIds(contactTagPivotIdList);
        }
        removeById(tagId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveLabelByUser(WorkContactTagUserCreateDTO dto) {
        Integer corpId = CorpContextHolder.getCorpId();
        //用户信息
        WorkEmployeeEntity employeeEntity = employeeService.getOne(Wrappers
                .<WorkEmployeeEntity>lambdaQuery()
                .eq(WorkEmployeeEntity::getWxUserId, dto.getWxUserId())
                .eq(WorkEmployeeEntity::getCorpId,corpId));
        //客户信息
        WorkContactEntity contactEntity = contactService.getOne(Wrappers
                .<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getWxExternalUserid, dto.getWxExternalUserid())
                .eq(WorkContactEntity::getCorpId,corpId));

        ArrayList<Integer> integers = new ArrayList<>();
        ArrayList<Integer> tags = new ArrayList<>();
        ArrayList<Integer> newTags = new ArrayList<>();
        dto.getWxList().forEach(workContactTagUserGroupCreateDTO -> {
            Integer groupId = workContactTagUserGroupCreateDTO.getGroupId();
            workContactTagUserGroupCreateDTO.getTagNameList().forEach(workContactTagUserGroupListCreateDTO -> {
//                String wxContactTagId = workContactTagUserGroupListCreateDTO.getWxContactTagId();
//                WorkContactTagEntity tagEntity = tagService.getOne(Wrappers
//                        .<WorkContactTagEntity>lambdaQuery()
//                        .eq(WorkContactTagEntity::getWxContactTagId, wxContactTagId));
//                integers.add(tagEntity.getId());
                integers.add(workContactTagUserGroupListCreateDTO.getId());
            });
        });
        List<GetContactTapModel> tag = iContactService.getContactInfo(contactEntity.getId(), employeeEntity.getId(), CorpContextHolder.getCorpId()).getTag();
        for (int i = 0; i < tag.size(); i++) {
            tags.add(tag.get(i).getTagId());
        }
        if(integers.size()>tags.size()){
            for (int i = 0; i < integers.size(); i++) {
                for (int j = 0; j < tags.size(); j++) {
                    if(integers.get(i).equals(tags.get(j))){
                        newTags.add(tags.get(j));
                    }
                }
            }
        }else {
            newTags.addAll(tags);
        }
        if (!newTags.isEmpty()){
            contactTagPivotService.remove(Wrappers.<WorkContactTagPivotEntity>lambdaQuery()
                    .eq(WorkContactTagPivotEntity::getContactId,contactEntity.getId())
                    .eq(WorkContactTagPivotEntity::getEmployeeId,employeeEntity.getId())
                    .in(WorkContactTagPivotEntity::getContactTagId,newTags));
        }

        List<Integer> tagIds = new LinkedList<>();
        //存放客户-标签对应数据
        integers.forEach(wxContactTagId->{
            WorkContactTagPivotEntity workContactTagPivotEntity = new WorkContactTagPivotEntity();
            workContactTagPivotEntity.setContactId(contactEntity.getId());
            workContactTagPivotEntity.setEmployeeId(employeeEntity.getId());
            workContactTagPivotEntity.setContactTagId(wxContactTagId);
            workContactTagPivotEntity.setType(2);
            tagIds.add(wxContactTagId);
            contactTagPivotService.save(workContactTagPivotEntity);
        });

        //企业标签信息
        List<WorkContactTagPivotEntity> list = contactTagPivotService.list(Wrappers.<WorkContactTagPivotEntity>lambdaQuery()
                .eq(WorkContactTagPivotEntity::getContactId, contactEntity.getId())
                .eq(WorkContactTagPivotEntity::getEmployeeId, employeeEntity.getId()));
        List<Integer> tagsId= new LinkedList<>();
        list.forEach(l->{
            tagsId.add(l.getContactTagId());
        });

        StringBuilder stringBuffer = new StringBuilder();
        if (!tagsId.isEmpty()){
            List<WorkContactTagEntity> tagEntityList = baseMapper.selectBatchIds(tagsId);
            for (WorkContactTagEntity e : tagEntityList) {
                stringBuffer.append("、【").append(e.getName()).append("】");
            }
            contactEmployeeTrackService.saveTrack(employeeEntity.getId(),contactEntity.getId(),EventEnum.TAG,employeeEntity.getName()+"对该客户打标签" + stringBuffer.substring(1),2,corpId);
        }
    }

    @Override
    public void saveLabelByConsole(WorkContactTagsAddDTO dto) {
        //企业标签信息
        ArrayList<Integer> integers = new ArrayList<>();
        ArrayList<Integer> tags = new ArrayList<>();
        ArrayList<Integer> newTags = new ArrayList<>();
        dto.getTagList().forEach(workContactTagUserGroupCreateDTO -> {
            workContactTagUserGroupCreateDTO.getTagNameList().forEach(workContactTagUserGroupListCreateDTO -> {
//                String wxContactTagId = workContactTagUserGroupListCreateDTO.getWxContactTagId();
                Integer tagId = workContactTagUserGroupListCreateDTO.getId();
                WorkContactTagEntity tagEntity = tagService.getOne(Wrappers
                        .<WorkContactTagEntity>lambdaQuery()
//                        .eq(WorkContactTagEntity::getWxContactTagId, wxContactTagId)
                        .eq(WorkContactTagEntity::getId, tagId)
                );
                integers.add(tagEntity.getId());
            });
        });
        List<GetContactTapModel> tag = iContactService.getContactInfo(dto.getContactId(), dto.getEmployeeId(), CorpContextHolder.getCorpId()).getTag();
        for (int i = 0; i < tag.size(); i++) {
            tags.add(tag.get(i).getTagId());
        }
        if(integers.size()>tags.size()){
            for (int i = 0; i < integers.size(); i++) {
                for (int j = 0; j < tags.size(); j++) {
                    if(integers.get(i).equals(tags.get(j))){
                        newTags.add(tags.get(j));
                    }
                }
            }
        }else {
            newTags.addAll(tags);
        }
        if (!newTags.isEmpty()){
            contactTagPivotService.remove(Wrappers.<WorkContactTagPivotEntity>lambdaQuery()
                    .eq(WorkContactTagPivotEntity::getContactId,dto.getContactId())
                    .eq(WorkContactTagPivotEntity::getEmployeeId,dto.getEmployeeId())
                    .in(WorkContactTagPivotEntity::getContactTagId,newTags));
        }
        List<Integer> tagIds = new LinkedList<>();
        //存放客户-标签对应数据
        integers.forEach(wxContactTagId->{
            WorkContactTagPivotEntity workContactTagPivotEntity = new WorkContactTagPivotEntity();
            workContactTagPivotEntity.setContactId(dto.getContactId());
            workContactTagPivotEntity.setEmployeeId(dto.getEmployeeId());
            workContactTagPivotEntity.setContactTagId(wxContactTagId);
            workContactTagPivotEntity.setType(1);
            tagIds.add(wxContactTagId);
            contactTagPivotService.save(workContactTagPivotEntity);
        });
        List<WorkContactTagPivotEntity> list = contactTagPivotService.list(Wrappers.<WorkContactTagPivotEntity>lambdaQuery()
                .eq(WorkContactTagPivotEntity::getContactId, dto.getContactId())
                .eq(WorkContactTagPivotEntity::getEmployeeId, dto.getEmployeeId()));
        List<Integer> tagsId= new LinkedList<>();
        list.forEach(l->{
            tagsId.add(l.getContactTagId());
        });

        StringBuilder stringBuffer = new StringBuilder();
        if (!tagsId.isEmpty()){
            List<WorkContactTagEntity> tagEntityList = baseMapper.selectBatchIds(tagsId);
            for (WorkContactTagEntity e : tagEntityList) {
                stringBuffer.append("、【").append(e.getName()).append("】");
            }
            WorkEmployeeEntity one = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery().eq(WorkEmployeeEntity::getCorpId,CorpContextHolder.getCorpId()).eq(WorkEmployeeEntity::getId, dto.getEmployeeId()));
            contactEmployeeTrackService.saveTrack(dto.getEmployeeId(),dto.getContactId(),EventEnum.TAG,one.getName()+"对该客户打标签" + stringBuffer.substring(1),1,CorpContextHolder.getCorpId());
        }
    }


    @Override
    public List<WorkContactTagUserVO> selectLabelByUser(String wxExternalUserid, String wxUserId) {
        Integer corpId = CorpContextHolder.getCorpId();
        //用户信息
        WorkEmployeeEntity employeeEntity = employeeService.getOne(Wrappers
                .<WorkEmployeeEntity>lambdaQuery()
                .eq(WorkEmployeeEntity::getWxUserId,wxUserId)
                .eq(WorkEmployeeEntity::getCorpId,corpId));
        //客户信息
        WorkContactEntity contactEntity = contactService.getOne(Wrappers
                .<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getWxExternalUserid, wxExternalUserid)
                .eq(WorkContactEntity::getCorpId,corpId));
        //查询当前客户绑定的企业标签
        List<Map> label = baseMapper.selectLabelByContact(contactEntity.getId(), employeeEntity.getId());

        //   List<Map> maps = baseMapper.selectLabelByUser(wxExternalUserid, wxUserId);
        ArrayList<WorkContactTagUserVO> workContactTagUserVOS = new ArrayList<>();
        label.forEach(map -> {
            WorkContactTagUserVO workContactTagUserVO = new WorkContactTagUserVO();
            Long groupId =(Long) map.get("groupId");
            Integer group=Integer.parseInt(String.valueOf(groupId));
            workContactTagUserVO.setGroupId(group);
            workContactTagUserVO.setGroupName((String) map.get("groupName"));
            workContactTagUserVOS.add(workContactTagUserVO);
        });
        for (int i = 0; i < workContactTagUserVOS.size() - 1; i++) {
            for (int j = workContactTagUserVOS.size() - 1; j > i; j--) {
                if (workContactTagUserVOS.get(i).equals(workContactTagUserVOS.get(j))) {
                    workContactTagUserVOS.remove(j);
                }
            }
        }
        workContactTagUserVOS.forEach(workContactTagUserVO -> {
            ArrayList<WorkContactTagUserListVO> workContactTagUserListVOS = new ArrayList<>();
            label.forEach(map1 -> {
                Integer groupId = workContactTagUserVO.getGroupId();
                Integer id1 =Integer.parseInt(String.valueOf((Long) map1.get("tagId"))) ;
                String name = (String) map1.get("name");
                String wx_contact_tag_id =(String) map1.get("wx_contact_tag_id");
                if(Integer.parseInt(String.valueOf((Long) map1.get("groupId")))==(groupId)){
                    WorkContactTagUserListVO workContactTagUserListVO = new WorkContactTagUserListVO();
                    workContactTagUserListVO.setId(id1);
                    workContactTagUserListVO.setName(name);
                    workContactTagUserListVO.setWxContactTagId(wx_contact_tag_id);
                    workContactTagUserListVOS.add(workContactTagUserListVO);
                }
            });
            workContactTagUserVO.setTagNameList(workContactTagUserListVOS);
        });
        List<WorkContactTagUserVO> collect = workContactTagUserVOS.stream().sorted(Comparator.comparing(WorkContactTagUserVO::getGroupId).reversed()).collect(Collectors.toList());
        return collect;
    }

    @Override
    public List<WorkContactCrmTagVO> getCrmTagListByWxUserId(String wxExternalUserid, String wxUserId) {
        ArrayList<WorkContactCrmTagVO> vos = new ArrayList<>();
        WorkEmployeeEntity employeeEntity = workEmployeeService.getOne(new LambdaQueryWrapper<WorkEmployeeEntity>()
                .eq(WorkEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(WorkEmployeeEntity::getWxUserId, wxUserId));

        WorkContactEntity contactEntity = iContactService.getOne(new LambdaQueryWrapper<WorkContactEntity>()
                .eq(WorkContactEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(WorkContactEntity::getWxExternalUserid, wxExternalUserid));

        WorkContactEmployeeEntity contactEmployeeEntity = workContactEmployeeService.getOne(new LambdaQueryWrapper<WorkContactEmployeeEntity>()
                .eq(WorkContactEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(WorkContactEmployeeEntity::getContactId, contactEntity.getId())
                .eq(WorkContactEmployeeEntity::getEmployeeId, employeeEntity.getId()));
        if (contactEmployeeEntity == null || JSONArray.parseArray(contactEmployeeEntity.getRemarkMobiles()).isEmpty()) {
            return vos;
        }
        //关联CRM标签同步表
        String mobile = JSONArray.parseArray(contactEmployeeEntity.getRemarkMobiles()).get(0).toString();
        CrmCustomQueryConditionDTO queryCondition = new CrmCustomQueryConditionDTO();
        queryCondition.setMobileTel(mobile);
        List<WorkCustomInfoEntity> workCustomInfoEntitys = workCustomInfoService.listByCondition(queryCondition);
        if (workCustomInfoEntitys.isEmpty()) {
            return vos;
        }
        List<WorkCustTagInfoEntity> workCustTagInfoEntities = workCustTagInfoService.listByCustNo(workCustomInfoEntitys.get(0).getCustNo());
        if (workCustTagInfoEntities.isEmpty()) {
            return vos;
        }
        WorkCustTagInfoEntity workCustTagInfoEntity = workCustTagInfoEntities.get(0);
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getFinFlag().equals("1") ? "理财签约" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getIsThirdDept().equals("1") ? "三方存管" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getIsPotentialCust().equals("1") ? "潜力客户" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getNoneLoanAcct().equals("1") ? "无贷户" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getHrsdFlag().equals("1") ? "华融闪贷" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getEbankFlag().equals("1") ? "网上银行" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getIsEbkActiveFlag().equals("1") ? "网银银行激活" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getMobileBankCust().equals("1") ? "手机银行" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getIsMbkActiveFlag().equals("1") ? "手机银行激活" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getPbankCust().equals("1") ? "电话银行" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getIsSmCust().equals("1") ? "短信签约" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getWbkCust().equals("1") ? "微信银行" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getVipCardCust().equals("1") ? "VIP卡" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getWageAcct().equals("1") ? "工资卡" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getCrcdCust().equals("1") ? "信用卡客户" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getCcaliveBankCust().equals("1") ? "信用卡激活客户" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getCcthreeBankCust().equals("1") ? "信用卡有效刷卡客户" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getIsExec().equals("1") ? "企业高管" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getIsBene().equals("1") ? "企业受益人" : null));
        vos.add(new WorkContactCrmTagVO(workCustTagInfoEntity.getIsSmsOpen().equals("1") ? "短信提醒" : null));
        vos.removeIf(v->
                StrUtil.isBlank(v.getTagName())
        );
        return vos;
    }
}
